const fs = require('fs');
const path = require('path');
const { DateTime } = require('luxon');
const db = require('../config/db');
const mysql = require('mysql2/promise');

// 创建数据库连接池
const pool = mysql.createPool({
  host: '182.160.6.140',
  user: 'root',
  password: 'BinanceRoot2023',
  database: 'binance_klines',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

// 缓存文件路径
const CACHE_DIR = path.join(__dirname, '../../cache');
const CACHE_FILE = symbol => path.join(CACHE_DIR, `${symbol}_stats.json`);

// 确保缓存目录存在
if (!fs.existsSync(CACHE_DIR)) {
  fs.mkdirSync(CACHE_DIR, { recursive: true });
}

// 确保公共API目录存在
const PUBLIC_API_DIR = path.join(__dirname, '../../public/api/stats');
if (!fs.existsSync(PUBLIC_API_DIR)) {
  fs.mkdirSync(PUBLIC_API_DIR, { recursive: true });
}

// 时间范围定义
const TIME_RANGES = {
  '1m': { months: 1 },
  '3m': { months: 3 },
  '6m': { months: 6 },
  '1y': { years: 1 },
  '2y': { years: 2 }
};

// 计算统计数据
async function calculateStats(symbol, interval, startTime, endTime) {
  const tableName = `kline_${interval}_enhanced`;
  
  // 查询总K线数量
  const [totalResult] = await pool.query(
    `SELECT COUNT(*) as total FROM ${tableName} 
     WHERE symbol = ? AND open_time BETWEEN ? AND ?`,
    [symbol, startTime, endTime]
  );
  
  // 查询上涨K线数量
  const [upResult] = await pool.query(
    `SELECT COUNT(*) as up FROM ${tableName} 
     WHERE symbol = ? AND open_time BETWEEN ? AND ? 
     AND close_price > open_price`,
    [symbol, startTime, endTime]
  );
  
  // 查询下跌K线数量
  const [downResult] = await pool.query(
    `SELECT COUNT(*) as down FROM ${tableName} 
     WHERE symbol = ? AND open_time BETWEEN ? AND ? 
     AND close_price < open_price`,
    [symbol, startTime, endTime]
  );

  // 获取总K线数量
  const totalKlines = totalResult[0].total;

  // 直接使用SQL查询获取连续上涨数据 - 修改计算逻辑
  const [upStreakResults] = await pool.query(
    `SELECT count, COUNT(*) as occurrences 
     FROM (
       SELECT 
         @streak := IF(@prev_symbol = BINARY symbol AND @prev_close < close_price, 
                      @streak + 1, 
                      IF(@prev_symbol = BINARY symbol AND @prev_close >= close_price, 0, 1)
                    ) AS count,
         @prev_symbol := symbol, 
         @prev_close := close_price
       FROM ${tableName}, 
         (SELECT @streak := 0, @prev_symbol := '', @prev_close := 0) AS vars
       WHERE symbol = ? 
         AND open_time BETWEEN ? AND ?
       ORDER BY symbol, open_time
     ) AS streaks 
     WHERE count >= 2
     GROUP BY count`,
    [symbol, startTime, endTime]
  );

  // 直接使用SQL查询获取连续下跌数据 - 修改计算逻辑
  const [downStreakResults] = await pool.query(
    `SELECT count, COUNT(*) as occurrences 
     FROM (
       SELECT 
         @streak := IF(@prev_symbol = BINARY symbol AND @prev_close > close_price, 
                      @streak + 1, 
                      IF(@prev_symbol = BINARY symbol AND @prev_close <= close_price, 0, 1)
                    ) AS count,
         @prev_symbol := symbol, 
         @prev_close := close_price
       FROM ${tableName}, 
         (SELECT @streak := 0, @prev_symbol := '', @prev_close := 0) AS vars
       WHERE symbol = ? 
         AND open_time BETWEEN ? AND ?
       ORDER BY symbol, open_time
     ) AS streaks 
     WHERE count >= 2
     GROUP BY count`,
    [symbol, startTime, endTime]
  );

  // 将结果转换为对象格式，计算占比
  const consecutiveUp = {};
  const consecutiveDown = {};

  upStreakResults.forEach(row => {
    // 计算占比 - 连续K线数量占总K线的百分比
    const percentage = totalKlines > 0 ? (row.occurrences / totalKlines * 100).toFixed(2) : 0;
    consecutiveUp[row.count] = {
      occurrences: row.occurrences,
      percentage: parseFloat(percentage)
    };
  });

  downStreakResults.forEach(row => {
    // 计算占比 - 连续K线数量占总K线的百分比
    const percentage = totalKlines > 0 ? (row.occurrences / totalKlines * 100).toFixed(2) : 0;
    consecutiveDown[row.count] = {
      occurrences: row.occurrences,
      percentage: parseFloat(percentage)
    };
  });

  // 返回完整的统计数据
  return {
    total: totalResult[0].total,
    up: upResult[0].up,
    down: downResult[0].down,
    flat: totalResult[0].total - upResult[0].up - downResult[0].down,
    consecutive: {
      up: consecutiveUp,
      down: consecutiveDown
    }
  };
}

// 更新缓存并保存为静态文件
async function updateCache(symbol, interval) {
  try {
    // 使用系统当前时间，确保时区正确
    const now = DateTime.now().setZone('Asia/Hong_Kong');
    console.log(`当前系统时间: ${now.toFormat('yyyy-MM-dd HH:mm:ss')}`);
    
    const stats = {};
    
    // 对每个时间范围计算统计数据
    for (const [range, duration] of Object.entries(TIME_RANGES)) {
      const startTime = now.minus(duration).toMillis();
      const endTime = now.toMillis();
      
      console.log(`计算 ${symbol} ${interval} ${range} 统计数据，时间范围: ${now.minus(duration).toFormat('yyyy-MM-dd HH:mm:ss')} 至 ${now.toFormat('yyyy-MM-dd HH:mm:ss')}`);
      
      const data = await calculateStats(symbol, interval, startTime, endTime);
      
      // 保存到缓存
      stats[range] = {
        data,
        lastUpdate: now.toMillis()
      };
      
      // 将结果保存为静态JSON文件
      const jsonFilePath = path.join(PUBLIC_API_DIR, `${symbol.toLowerCase()}_${interval}_${range}.json`);
      const jsonContent = JSON.stringify({
        code: 0,
        data: {
          ...data,
          timeRange: {
            start: now.minus(duration).toFormat('yyyy-MM-dd HH:mm:ss'),
            end: now.toFormat('yyyy-MM-dd HH:mm:ss'),
            range
          }
        },
        msg: 'success'
      }, null, 2);
      
      fs.writeFileSync(jsonFilePath, jsonContent);
      console.log(`已更新静态JSON文件: ${jsonFilePath}`);
    }
    
    // 保存完整缓存文件
    const cacheFilePath = getCacheFilePath(symbol, interval);
    const cacheContent = JSON.stringify({
      lastUpdate: now.toMillis(),
      stats
    }, null, 2);
    
    fs.writeFileSync(cacheFilePath, cacheContent);
    console.log(`已更新缓存文件: ${cacheFilePath}`);
    
    return stats;
  } catch (error) {
    console.error(`更新缓存失败: ${error.message}`);
    throw error;
  }
}

// 获取缓存文件路径
function getCacheFilePath(symbol, interval) {
  return path.join(CACHE_DIR, `${symbol.toLowerCase()}_${interval}_cache.json`);
}

// 从缓存获取统计数据
function getStatsFromCache(symbol, interval, range) {
  try {
    const cacheFilePath = getCacheFilePath(symbol, interval);
    
    // 如果缓存文件不存在，返回null
    if (!fs.existsSync(cacheFilePath)) {
      return null;
    }
    
    // 读取缓存文件
    const cacheContent = fs.readFileSync(cacheFilePath, 'utf8');
    const cache = JSON.parse(cacheContent);
    
    // 检查是否存在请求的范围数据
    if (!cache.stats || !cache.stats[range]) {
      return null;
    }
    
    // 检查缓存是否过期（超过1周）
    const lastUpdate = cache.lastUpdate;
    const now = DateTime.now().toMillis();
    const oneWeek = 7 * 24 * 60 * 60 * 1000; // 一周的毫秒数
    
    if (now - lastUpdate > oneWeek) {
      return null;
    }
    
    // 返回缓存的数据
    return cache.stats[range].data;
  } catch (error) {
    console.error(`从缓存获取数据失败: ${error.message}`);
    return null;
  }
}

module.exports = {
  TIME_RANGES,
  getStatsFromCache,
  updateCache,
  calculateStats
}; 